package com.xiaochong.tir.common.util;



import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**  时间工具类
 * Created by caox on 2016/5/31.
 */
public class DateUtils {


    /**
     * yyyy-MM-dd HH:mm:ss
     */
	public static DateTimeFormatter format_ymdhms = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    /**
     * yyyy-MM-dd HH:mm:ss.SSS
     */
    public static DateTimeFormatter format_ymdhmssss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
    /**
     * yyyyMMdd
     */
    public static DateTimeFormatter format_ymds = DateTimeFormatter.ofPattern("yyyyMMdd");
	/**
     * yyyyMMddHHmm
     */
	public static DateTimeFormatter format_ymdhm = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
	/**
     * yyyyMMddHH
     */
	public static DateTimeFormatter format_ymdh = DateTimeFormatter.ofPattern("yyyyMMddHH");
    /**
     * yyyy-MM-dd
     */
    public static DateTimeFormatter format_ymd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    /**
     * yyyy-MM-dd HH:mm
     */
    public static DateTimeFormatter format_ymdhm_x = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    /**
     * yyyy-MM-dd HH
     */
    public static DateTimeFormatter format_ymdh_x = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");

    /**
     * yyyy-MM-dd
     */
    public static DateTimeFormatter formatm_d = DateTimeFormatter.ofPattern("MM-dd");
    /**
     * 获取当前时间
     * @return
     * @throws Exception
     */
    public static LocalDateTime getCurrentDate(){
    	LocalDateTime now = LocalDateTime.now();
    	return now;
    }
    
    
    /**
     * 获取当前时间字符串，格式为yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getCurrentDateStr(){
    	String nowtime=getCurrentDate().format(format_ymdhmssss);
    	return nowtime;
    }
    
    /**
     * 获取前几个小时的时间
     * @param hours
     * @return
     */
    public static String getLastHourDateStr(long hours){
    	return LocalDateTime.now().minusHours(hours).format(format_ymdhms);
    }
    /**
     * 获取前几个小时的时间返回日期，去掉小时
     * @param hours
     * @return
     */
    public static String getLastHourDateStrOfDate(long hours){
        return LocalDateTime.now().minusHours(hours).format(format_ymds);
    }
    /**
     * 获取当前时间字符串，格式为yyyyMMdd
     * @return
     */
    public static String getCurrentDateString(){
    	String nowtime=getCurrentDate().format(format_ymds);
    	return nowtime;
    }
    
    /**
     * 获取days天后的当前时间（yyyy-MM-dd HH:mm:ss）
     * @param days
     * @return
     */
    public static String getNextDayDateStr(int days){
    	return LocalDateTime.now().plusDays(days).format(format_ymdhms);
    }
    
    /**
     * 获取days天后的当前时间（yyyyMMdd）
     * @param days
     * @return
     */
    public static String getNextDayDateYMD(int days){
    	return LocalDateTime.now().plusDays(days).format(format_ymds);
    }

    /**
     * 获取days天后的当前时间（yyyyMMdd）
     * @param days
     * @return
     */
    public static String getNextDayDateYMD2(int days){
        return LocalDateTime.now().plusDays(days).format(format_ymd);
    }

    /**
     * 获取当前时间字符串，格式为yyyy-MM-dd
     * @return
     */
    public static String getCurrentDateStrymd(){
        String nowtime=getCurrentDate().format(format_ymd);
        return nowtime;
    }

    /**
     * 获取当前时间字符串，格式为yyyy-MM-dd HH:mm:ss.SSS
     * @return
     */	
    public static String getCurrentDateStr_MS(){
    	String nowtime=getCurrentDate().format(format_ymdhmssss);
    	return nowtime;
    }
    
    
    
    /**
     * 获取当前时间long值
     * @return
     */
    public static long getCurrentDataLong(){
        return System.currentTimeMillis();
    }



    

    

    /**
     * 将给定的时间秒转换为中文格式的时分秒
     * @param second
     * @return
     */
    public static String formatSecond_ZH_HMS(Integer second) {
        String result = "0秒";
        if (null != second) {
            int hours = (int) (second / (60 * 60));
            int minutes = (int) (second / 60 - hours * 60);
            int seconds = (int) (second - minutes * 60 - hours * 60 * 60);

            String format;
            Object[] array;

            if (hours > 0) {
                format = "%1$,d时%2$,d分%3$,d秒";
                array = new Object[]{hours, minutes, seconds};
            } else if (minutes > 0) {
                format = "%1$,d分%2$,d秒";
                array = new Object[]{minutes, seconds};
            } else {
                format = "%1$,d秒";
                array = new Object[]{seconds};
            }
            result = String.format(format, array);
        }
        return result;
    }

    
    

    /**
     * 比较两个日期的大小
     *
     * @param date1
     * @param date2
     * @return 日期相等，返回0；前者大，返回1；后者大，返回-1；
     */
    public static int dateCompare(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);

        return c1.compareTo(c2);
    }

    /**
     * 判断当前日期是否在指定日期区域内(包含起止日期) [startDate,endDate]
     * <p/>
     * [null,null] --> return 1;
     *
     * @param now
     * @param startDate
     * @param endDate
     * @return -1：超出并小于startDate；0:在范围内；1：超出并大于endDate；
     */
    public static int validateDate(Date now, Date startDate, Date endDate) {
        if (null == startDate && null == endDate) {
            return 0;
        }
        if (null == startDate) {
            //当前时间大于endDate
            if (dateCompare(now, endDate) == 1) {
                return 1;
            } else {
                return 0;
            }
        } else {
            if (null == endDate) {
                //当前时间小于startDate
                if (dateCompare(startDate, now) == 1) {
                    return -1;
                } else {
                    return 0;
                }
            } else {
                if (dateCompare(startDate, now) == 1) {
                    return -1;
                } else if (dateCompare(now, endDate) == 1) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
    }

    /**
     * 计算两个日期相差多少秒
     * @param pre 前一个日期
     * @param after 后一个日期
     * @return
     */
    public static long calTimeDifference(Date pre,Date after){
        return (after.getTime()-pre.getTime())/1000;
    }


    /**
     * 对日期进行加法操作
     * @param date
     * @param days
     * @return
     */
    public static Date addDay(Date date, Integer days) {
        if (null != date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.add(Calendar.DATE, days);
            return cal.getTime();
        }
        return null;
    }

    /**
     * 对时间进行加法操作
     * @param date
     * @param hours
     * @return
     */
    public static Date addHours(Date date, Integer hours) {
        if (null != date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.add(Calendar.HOUR_OF_DAY, hours);
            return cal.getTime();
        }
        return null;
    }
    

    
    /**
     * 某个时间加多少分钟
     * @param date
     * @param minute
     * @return
     */
    public static Date getDateByAddMinute(Date date,int minute) {
    	if (date == null) {
    		return null;
    	}
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(date);  
        cal.add(Calendar.MINUTE, minute);// 24小时制  
    	return cal.getTime();
    }
    
    
    /**
     * 比较两个日期的大小
     * @param d1
     * @param d2
     * @return d2 > d1  true
     */
    public static boolean compareTime(Date d1,Date d2){
    	if(d1==null || d2==null) {
    		return false;
    	}
        if (d1.getTime() < d2.getTime()) {
            return true;
        } else {//相等
            return false;
        }
    }
    
    
    
    /**
     * 结束时间与当前时间计算相差的月数
     * @param enddate
     * @return
     */
    public static int getMonthSpace(String enddate, DateTimeFormatter format) {
    	LocalDate formatted = LocalDate.parse(enddate,format);
        LocalDate today = LocalDate.now();
        Period per = Period.between(today,formatted);
        if(per.getYears() == 0 ){
        	return per.getMonths();
        }else if(per.getYears() > 0 ){
        	return (per.getYears() * 12) + per.getMonths();
        }
        
        return (per.getYears() * 12) + per.getMonths();
    }


    /**
     * 将String 格式的时间转换为Date
     * @param createDate
     * @param format 时间格式
     * @return
     */
    public static Date getDate(String createDate, DateTimeFormatter format){
        LocalDateTime dateTime = LocalDateTime.parse(createDate,format);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = dateTime.atZone(zone).toInstant();
        return  Date.from(instant);

    }


    
    /**
     * 获取某个时间段之前的时间点
     * 返回yyyy-MM-dd HH:mm:ss格式
     * @param sign ：day-天  week-周  month-月  year-年
     * @return
     */
    public static String getSomeTimeDateStr(String sign){
    	String beginTime="";
    	LocalDateTime beginDateTime =null;
    	if (sign.equals("day")) {//一天前时间
    		beginDateTime =LocalDateTime.now().minusDays(1L);
		}else if(sign.equals("week")){
			beginDateTime =LocalDateTime.now().minusWeeks(1L);
		}else if (sign.equals("month")) {
			beginDateTime =LocalDateTime.now().minusMonths(1L);
		}else if (sign.equals("year")) {
			beginDateTime =LocalDateTime.now().minusYears(1L);
		}
    	if (beginDateTime!=null) {
    		beginTime = beginDateTime.format(format_ymdhms);
		}
    	return beginTime;
    }



    /**
     * 获取失效时间点（在什么时间失效）
     * @param minutes       有效分钟数
     * @return
     */
    public static LocalDateTime getInvalidLocalDateTime(Long minutes){
        return LocalDateTime.now().minusMinutes(minutes);
    }


    /**
     * 获取当前年份
     * @return
     */
    public static String getCurrentYear(){
        Calendar instance = Calendar.getInstance();
        return instance.get(Calendar.YEAR)+"";
    }


    /**
     * 获取当前月份
     * @return
     */
    public static String getCurrentMonth(){
        Calendar instance = Calendar.getInstance();
        int month = instance.get(Calendar.MONTH)+1;
        String result;
        if (month < 10){
            result = "0" + month;
        }else {
            result = month+"";
        }
        return result;
    }

    /**
     * 获取两个日期之间的所有日期集合
     */
    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
        List<Date> lDate = new ArrayList<Date>();
        lDate.add(beginDate);// 把开始时间加入集合
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(beginDate);
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (endDate.after(cal.getTime())) {
                lDate.add(cal.getTime());
            } else {
                break;
            }
        }
        //lDate.add(endDate);// 把结束时间加入集合
        return lDate;
    }



    
    /**
     * 检验字符串是否为合法的格式日期格式
     * @param str
     * @param  dateTimeFormatter 日期格式
     * @return
     */
    public static boolean checkStrMatchYmdhms(String str,DateTimeFormatter dateTimeFormatter){
    	try {
            dateTimeFormatter.parse(str);
		} catch (Exception e) {
			return false;
		}
    	return true;
    }



    

    

    
    /**
     * 计算两个日期相差得天数
     */
    public static int getDaysBetweenTwoDate(Date start ,Date end){
    	int days = (int) ((start.getTime() - end.getTime()) / (1000*3600*24));
        return days;
    }
    
    
    
    
    /**
     * 比较两个日期的大小
     * @param d1
     * @param d2
     * @return d1 > d2 return 1
     *         d1 < d2 return -1
     *         d1 = d2 return 0
     */
    public static int compareDate(Date d1,Date d2){
        if (d1.getTime() > d2.getTime()) {
            return 1;
        } else if (d1.getTime() < d2.getTime()) {
            return -1;
        } else {//相等
            return 0;
        }
    }


    /**
     * 获取年月
     * date为空时返回当前月份
     * @param date 格式：xxxx-xx 例如：2018-01
     * @param amount 数量
     * @return date月份+amount后的日期
     */
    public static String getMonth(String date,int amount, DateTimeFormatter format) {
        if(StringUtils.isBlank(date)) {

            return getCurrentDate().format(format);
        }
        Calendar cal = Calendar.getInstance();
        LocalDate localDate = LocalDate.parse(date,format_ymd);
        LocalDateTime dateTime = LocalDateTime.from(localDate.atStartOfDay());
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = dateTime.atZone(zone).toInstant();
        cal.setTime(Date.from(instant));
        cal.add(Calendar.MONTH,amount);
        instant = cal.getTime().toInstant();
        zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);

        return  localDateTime.format(format);

    }

    /**
     * 将Date 转换成字符串
     * @param date
     * @param format 时间格式
     * @return 转换后的字符串时间
     */
    public static String dateFormatString(Date date,DateTimeFormatter format){
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.format(format);
    }

    /**
     * 将localDateTime 转换成字符串
     * @param date
     * @param format 时间格式
     * @return 转换后的字符串时间
     */
    public static String localDateTimeFormatString(LocalDateTime localDateTime,DateTimeFormatter format){
        return localDateTime.format(format);
    }

    /**
     * 计算两个日期相差得小时
     */
    public static int getDaysBetweenTwoHours(Date start ,Date end){
        BigDecimal stb = new BigDecimal(start.getTime());
        BigDecimal endb = new BigDecimal(end.getTime());
        BigDecimal blong = stb.subtract(endb);
        BigDecimal chu = new BigDecimal(1000*3600);
        BigDecimal hours = BigDecimal.valueOf((start.getTime() - end.getTime()) / (1000*3600));
        BigDecimal result = blong.divide(chu,0,BigDecimal.ROUND_CEILING);
        return Integer.valueOf(String.valueOf(result));
    }
    public static void main(String[] args) {


        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM");
       // LocalDate.parse("2017-09",DateTimeFormatter.ISO_DATE);

       int h = DateUtils.getDaysBetweenTwoHours(new Date(),DateUtils.getDate("2018-04-28 00:00:00",DateUtils.format_ymdhms));
        System.out.println(h);
        System.out.println(dateFormatString(new Date(), format));

        String a=DateUtils.getCurrentDateString();
        System.out.println(a);
    }

    /**
     * date转localDateTime
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        if(date==null){
            return null;
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();

        return instant.atZone(zoneId).toLocalDateTime();
    }

    /**
     * localDateTime转date
     * @param localDateTime
     * @return
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        if(localDateTime==null){
            return null;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    /**
     * long类型转成LocalDateTime
     * @param timestamp
     * @return
     */
    public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }


    /**
     * String转成时间戳
     * @param timestamp
     * @return
     */
    public static Long getLongTIme(String date) {
        Long startDay = 0L;
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            Date dateStart = format.parse(date);
            startDay = (dateStart.getTime());
        }catch (ParseException e){
        }
        return startDay;
    }

    /**
     * String转成时间戳
     * @param timestamp
     * @return
     */
    public static Long getLongTIme2(String date) {
        Long startDay = 0L;
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date dateStart = format.parse(date);
            startDay = (dateStart.getTime());
        }catch (ParseException e){
        }
        return startDay;
    }

    /**
     * 字符串转long
     * @param date
     * @param format
     * @return
     */
    public static Long getLongTimeByFormat(String date,DateTimeFormatter format) {
        Long startDay = 0L;
        try {
           // SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date dateStart = getDate(date,format);
            startDay = (dateStart.getTime());
        }catch (Exception e){
            e.printStackTrace();
        }
        return startDay;
    }
    /**
     * 获取某年某月有多少天
     * @param year
     * @param month
     * @return
     */
    public static int getDayOfMonth(int year,int month) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, 0); //输入类型为int类型
        return c.get(Calendar.DAY_OF_MONTH);
    }
}
